import type { WindowPosition } from "@/core/window/window-position"
import type { WindowSize } from "@/core/window/window-size"

export type WindowResizeType =
  | "move"
  | "left"
  | "left-top"
  | "top"
  | "top-right"
  | "right"
  | "right-bottom"
  | "bottom"
  | "bottom-left"

//窗口大小变换处理器
export class WindowResizeProcessor {
  readonly position: WindowPosition
  readonly size: WindowSize
  type: WindowResizeType
  offset: {
    left: number
    top: number
    right: number
    bottom: number
  }

  constructor(
    position: WindowPosition,
    size: WindowSize,
    type: WindowResizeType,
    event: MouseEvent
  ) {
    this.position = position
    this.size = size
    this.type = type
    this.offset = this.position.offset(event)
  }

  public resize(event: MouseEvent) {
    if (!this.size.resizeHorizontal && !this.size.resizeVertical && this.type !== "move") {
      return
    }
    switch (this.type) {
      case "move":
        this.position.left = event.clientX - this.offset.left
        this.position.top = event.clientY - this.offset.top
        this.position.right = window.innerWidth - event.clientX - this.offset.right
        this.position.bottom = window.innerHeight - event.clientY - this.offset.bottom
        break
      case "left":
        this.resizeLeft(event)
        break
      case "left-top":
        this.resizeLeft(event)
        this.resizeTop(event)
        break
      case "top":
        this.resizeTop(event)
        break
      case "top-right":
        this.resizeTop(event)
        this.resizeRight(event)
        break
      case "right":
        this.resizeRight(event)
        break
      case "right-bottom":
        this.resizeRight(event)
        this.resizeBottom(event)
        break
      case "bottom":
        this.resizeBottom(event)
        break
      case "bottom-left":
        this.resizeBottom(event)
        this.resizeLeft(event)
        break
    }
  }

  private resizeLeft(event: MouseEvent) {
    if (this.size.resizeHorizontal) {
      this.position.left = event.clientX - this.offset.left
    }
    this.position.left = this.horizontalLimit(this.position.right) || this.position.left
  }

  private resizeTop(event: MouseEvent) {
    if (this.size.resizeVertical) {
      this.position.top = event.clientY - this.offset.top
    }
    this.position.top = this.verticallimit(this.position.bottom) || this.position.top
  }

  private resizeRight(event: MouseEvent) {
    if (this.size.resizeHorizontal) {
      this.position.right = window.innerWidth - event.clientX - this.offset.right
    }
    this.position.right = this.horizontalLimit(this.position.left) || this.position.right
  }

  private resizeBottom(event: MouseEvent) {
    if (this.size.resizeVertical) {
      this.position.bottom = window.innerHeight - event.clientY - this.offset.bottom
    }
    this.position.bottom = this.verticallimit(this.position.top) || this.position.bottom
  }

  private horizontalLimit(value: number) {
    if (window.innerWidth - this.position.left - this.position.right <= this.size.minWidth) {
      return window.innerWidth - value - this.size.minWidth
    }
    if (
      this.size.maxWidth &&
      window.innerWidth - this.position.left - this.position.right >= this.size.maxWidth
    ) {
      return window.innerWidth - value - this.size.maxWidth
    }
    return undefined
  }

  private verticallimit(value: number) {
    if (window.innerHeight - this.position.top - this.position.bottom <= this.size.minHeight) {
      return window.innerHeight - value - this.size.minHeight
    }
    if (
      this.size.maxHeight &&
      window.innerHeight - this.position.top - this.position.bottom >= this.size.maxHeight
    ) {
      return window.innerHeight - value - this.size.maxHeight
    }
    return undefined
  }
}
